// #include <iostream>
// using namespace std;
// #include <string>

// class House {
// 	/* 全局函数作友元 */
// 	friend void g_canVisit(House *pHouse);

// private:
// 	string bedroom;

// public:
// 	string livingroom;

// 	House();	//类内声明构造函数
// };

// //类外定义构造函数
// House::House() {
// 	livingroom = "客厅";
// 	bedroom = "卧室";
// }

// /* 全局函数 */
// void g_canVisit(House *pHouse) {
// 	cout << "正在访问：" << pHouse->livingroom << endl;

// 	//未对全局函数设置友元时，无法访问私有成员
// 	cout << "正在访问：" << pHouse->bedroom << endl;
// }

// int main() {
// 	House* house = new House;	//在堆区创建对象
// 	g_canVisit(house);			//正在访问：客厅；正在访问：卧室

// 	return 0;
// }

// #include <iostream>
// using namespace std;
// #include <string>

// /* 类的前向声明 */
// //Family类中未知House类的成员，仅能定义House类的指针、引用，以及House类作为形参或返回类型的函数声明
// class House;

// //友元类
// class Family {
// private:
// 	House* pHouse;

// public:
// 	Family();

// 	void canVisit();
// };

// class House {
// 	/* 类作友元 */
// 	friend class Family;

// private:
// 	string bedroom;		//私有成员

// public:
// 	string livingroom;	//公共成员

// 	House() {
// 		livingroom = "客厅";
// 		bedroom = "卧室";
// 	}
// };

// /* 为避免使用类的前向声明时误用该类成员报错，在类外定义成员函数 */
// Family::Family() {
// 	pHouse = new House;
// }

// void Family::canVisit() {
// 	cout << "正在访问：" << pHouse->livingroom << endl;	//使用前向声明类的成员

// 	//未对类设置友元时，无法访问私有成员
// 	cout << "正在访问：" << pHouse->bedroom << endl;	//使用前向声明类的成员
// }

// int main() {
// 	Family family;
// 	family.canVisit();	//正在访问：客厅；正在访问：卧室

// 	return 0;
// }

// #include <iostream>
// using namespace std;
// #include <string>

// /* 类的前向声明 */
// //Family类中未知House类的成员，仅能定义House类的指针、引用，以及House类作为形参或返回类型的函数声明
// class House;

// //友元类
// class Family {
// private:
// 	House *pHouse;

// public:
// 	Family();

// 	/* 对成员函数设置友元 */
// 	void canVisit();

// 	/* 未对成员函数设置友元 */
// 	void canNotVisit();
// };

// class House {
// 	/* 成员函数作友元 */
// 	friend void Family::canVisit();

// private:
// 	string bedroom;		//私有成员

// public:
// 	string livingroom;	//公共成员

// 	House() {
// 		this->livingroom = "客厅";
// 		this->bedroom = "卧室";
// 	}
// };

// /* 为避免使用类的前向声明时误用该类成员报错，在类外定义成员函数 */
// Family::Family() {
// 	pHouse = new House;
// }

// //对成员函数设置友元
// void Family::canVisit() {
// 	cout << "正在访问：" << pHouse->livingroom << endl;	//使用前向声明类的成员

// 	//对成员函数设置友元时，可访问私有成员
// 	cout << "正在访问：" << pHouse->bedroom << endl;	//使用前向声明类的成员
// }

// //未对成员函数设置友元
// void Family::canNotVisit() {
// 	cout << "正在访问：" << pHouse->livingroom << endl;	//使用前向声明类的成员

// 	//未对成员函数设置友元时，无法访问私有成员
// 	//cout << "正在访问：" << pHouse->bedroom << endl;
// }

// int main() {
// 	Family family;
// 	family.canVisit();		//正在访问：客厅；正在访问：卧室
// 	family.canNotVisit();	//正在访问：客厅

// 	return 0;
// }

//全局函数作友元函数的常规写法(声明放类内，定义放类外)

#include <iostream>
using namespace std;

class father
{
    friend int add(father &m_ff); //友元函数的类外实现
    int a;
    int b;

public:
    father(int m_a, int m_b) : a(m_a), b(m_b) {}
};

int add(father &m_ff)
{
    return (m_ff.a + m_ff.b);
};

int main()
{
    father ff(23, 32);
    // 友元函数不能用对象调用，友元函数是全局函数，就像调用普通函数那样调用
    cout << add(ff);
}

//也可以在类内完成友元函数的定义

#include <iostream>
using namespace std;

class father
{
    friend int add(father &m_ff)
    {
        return (m_ff.a + m_ff.b);
    }; //友元函数的类内实现




    int a;
    int b;

public:
    father(int m_a, int m_b) : a(m_a), b(m_b) {}
};

int main()
{
    father ff(23, 32);
    // 友元函数不能用对象调用
    cout << add(ff);
}